#include "output_document.h"
#include <iomanip>

namespace Pdf
{
	OutputDocument::OutputDocument(std::ostream &output)
		: output(output), trailer(new Dictionary())
    {    
		reftable[ Reference::Value( 0, 65535 ) ] = 0;    
	}

    OutputDocument::~OutputDocument()
    {
		trailer->set( "Size", new Integer( reftable.size() ) );

		PosType startxref = output.tellp();
		output << "xref"	  << std::endl;
		writeRefTable();
		output << "trailer"   << std::endl;
		output << *trailer    << std::endl;
		output << "startxref" << std::endl;
		output << startxref   << std::endl;
		output << "%%EOF";
    }

	void OutputDocument::write(const IndirectObject &obj)
	{
		reftable[obj.header->get()] = output.tellp();

		output << obj.header->get().id << " " << obj.header->get().gen << " obj" << std::endl;
		output << *obj.object;

		if (!obj.stream.empty())
		{
			// TODO: Encrypt stream
			output << std::endl << "stream" << std::endl;
			output.write( &obj.stream[0], obj.stream.size() );
			output << std::endl << "endstream";
		}

		output << std::endl << "endobj" << std::endl;
	}

	void OutputDocument::writeRefTable()
	{
		typedef std::list<RefTable::value_type> SubRefTable;

		for (RefTable::const_iterator i = reftable.begin(), end = reftable.end(); i != end; )
		{
			SubRefTable subtable;

			Integer::Value prev = i->first.id;
			do
			{
				subtable.push_back( *i );
			}
			while ( ++i != end && i->first.id == ++prev );

			output << subtable.begin()->first.id << " " << subtable.size() << std::endl;
			for (SubRefTable::const_iterator record = subtable.begin(); record != subtable.end(); ++record)
			{
				output << std::setfill('0') << std::setw(10) << record->second    << " ";
				output << std::setfill('0') << std::setw(5)  << record->first.gen << " ";
				output << (record->first.id == 0 ? 'f' : 'n') << "\r\n";
			}
		}
	}
}
